package com.cy.pj.sys.service.impl;

import com.cy.pj.common.annotation.RequiredLog;
import com.cy.pj.common.exception.ServiceException;
import com.cy.pj.sys.dao.SysUserDao;
import com.cy.pj.sys.dao.SysUserRoleDao;
import com.cy.pj.sys.pojo.SysUser;
import com.cy.pj.sys.service.SysUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.UUID;

@Service
public class SysUserServiceImpl implements SysUserService {
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysUserRoleDao sysUserRoleDao;

    @Transactional
    public int updateUser(SysUser entity){
        //开启事务
        //1.参数校验(省略)
        //2.更新用户自身信息
        int rows=sysUserDao.updateUser(entity);
        if(rows==0)
            throw new ServiceException("记录可能已经不存在");
        //3.更新用户和角色关系数据
        sysUserRoleDao.deleteByUserId(entity.getId());
        sysUserRoleDao.insertUserRoles(entity.getId(),
                entity.getRoleIds());
        return rows;
    }

    public SysUser findById(Integer id){
        SysUser user=sysUserDao.selectById(id);
        if(user==null)
            throw new ServiceException("此用户可能已经不存在");
        List<Integer> roleIds=sysUserRoleDao.selectRoleIdsByUserId(id);
        user.setRoleIds(roleIds);
        return user;
    }

    @Transactional(timeout = 500)
    public int saveUser(SysUser entity){
        //产生一个随机字符串作为加密盐使用
        String salt= UUID.randomUUID().toString();
        //对密码进行 MD5 盐值加密(MD5 特点:不可逆,相同内容加密结果也相同)
        SimpleHash sh=new SimpleHash("MD5",entity.getPassword(),salt,1);
        String hashedPassword=sh.toHex();
        entity.setSalt(salt);
        entity.setPassword(hashedPassword);
        int rows=sysUserDao.insertUser(entity);
        sysUserRoleDao.insertUserRoles(entity.getId(),entity.getRoleIds());
        return rows;
    }

    /**
     * @Transactional 注解描述方法时，此方法为一个事务切入点方法
     * @RequiresPermissions 描述方法时。此方法为一个授权切入点方法，
     * 我们在访问此方法时就需要授权，有权限则可以访问，没有权限则抛出异常。
     * 那如何判定用户有没有访问此方法的权限呢？当我们在方法时，shiro框架底层
     * 会获取此方法上的@RequiresPermissions注解，进而取到注解中的权限标识，
     * 然后会调用subject对象的checkPermissions(权限标识)方法检测用户是否有权限。
     * @param id 用户 id
     * @param valid 用户状态
     * @return
     */
    @RequiresPermissions("sys:user:update")
    @Transactional
    @Override
    public int  validById(Integer id,Integer valid){
        //获取用户权限Set<String> premissions
        //获取此方法上的权限标识"sys:user:update"
        //判断用户的权限中是否包含方法上的权限表示 flag=permissions.contains(sys:user:update)
        //if(flag){}else{}
        //String modifiedUser = "admin";
        SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();//获取当前用户
        String modifiedUser = user.getUsername();
        int rows=sysUserDao.validById(id,valid,modifiedUser);
        if(rows==0)throw new ServiceException("记录可能已经不存在");
        return rows;
    }

    @RequiredLog("日志分页查询")
    public List<SysUser> findUsers(SysUser sysUser){
        return sysUserDao.selectUsers(sysUser);
    }
}
